package cpm.lc.securitydemo.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;


@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private IAuthenticationSuccessHandler authenticationSuccessHandler;
    @Autowired
    private IAuthenticationFailureHandler authenticationFailureHandler;
    @Autowired
    private ILogoutHandler logoutHandler;
    @Autowired
    private ILogoutSuccessHandler logoutSuccessHandler;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //内存认证
        auth.inMemoryAuthentication()
                .withUser("root").password("123").roles("ADMIN", "DBA")
                .and()
                .withUser("user").password("123").roles("USER")
                .and()
                .withUser("admin").password("123").roles("ADMIN", "USER");

    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //授权请求
        http.authorizeRequests()
//                匹配以/admin/开头的所有请求
                .antMatchers("/admin/**")
//                具有ROLE_ADMIN角色才能访问上面的请求路径
                .hasRole("ADMIN")
                //匹配以/user/开头的所有请求
                .antMatchers("/user/**")
                //具有ROLE_ADMIN或ROLE_USER任一角色就能访问上面的请求路径
                .access("hasAnyRole('ADMIN','USER')")
                .antMatchers("/db/**")
                .access("hasRole('ADMIN') and hasRole('DBA')")
                //任何请求
                .anyRequest()
                //都需要已认证
                .authenticated()
                //和
                .and()
                //登录窗口
                .formLogin()
                //登录页面
                .loginPage("/login_page")
                //自定义用户名参数
                .usernameParameter("name")
                //自定义密码参数
                .passwordParameter("pwd")
                //登录处理网址
                .loginProcessingUrl("/login")
                //成功处理程序
                .successHandler(authenticationSuccessHandler)
                //失败处理器
                .failureHandler(authenticationFailureHandler)
                //允许所有 /login请求
                .permitAll()
                .and()
                //退出账户
                .logout()
                //登出网址
                .logoutUrl("/logout")
                //清除认证
                .clearAuthentication(true)
                //使 Http 会话无效
                .invalidateHttpSession(true)
                //添加注销处理程序
                .addLogoutHandler(logoutHandler)
                //注销成功处理程序
                .logoutSuccessHandler(logoutSuccessHandler)
                .and()
                //禁用跨站点请求伪造
                .csrf()
                .disable();

    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
}
